package com.oue.iot.auth;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.oue.redis.RedisUtils;

import jrain.fw.core.business.Business;
import jrain.fw.core.business.BusinessConst;
import jrain.fw.core.business.BusinessInterceptor;
import jrain.fw.core.business.BusinessMethod;
import jrain.fw.core.business.BusinessRequest;
import jrain.fw.core.business.BusinessResponse;
import jrain.fw.core.business.Interceptor;
import jrain.fw.core.dao.SqlRunner;
import jrain.fw.core.utils.FwUtils;
import jrain.utils.collection.CollectionUtils;
import jrain.utils.collection.RDMap;
import jrain.utils.collection.RMap;
import jrain.utils.consts.BaseConst;
import jrain.utils.lang.LangUtils;
import jrain.utils.lang.StringUtils;

@Business(name = "BaseAuthBusiness")
@Interceptor(name = "BaseAuth")
public class BaseAuthBusiness implements BusinessInterceptor {

	private static final String PRE = "base:auth:";
	private final List<String> authIgnoreList;
	private final List<String> authHalfList;
	private final int sessionTimeout;

	public SqlRunner getSqlRunner() {
		return FwUtils.getSqlRunnerManger().getSqlRunner(BaseConst.DEFAULT_VALUE);
	}

	public BaseAuthBusiness() {
		RMap<String, Object> cfg = FwUtils.getCfgService().getCfgMap("auth", new RDMap<String, Object>(new HashMap<>()));
		sessionTimeout = LangUtils.parseInt(cfg.get("session.timeout"), 30 * 24 * 60 * 60);
		authIgnoreList = CollectionUtils.valueOfList(StringUtils.trimNull(cfg.get("auth.ignore")));
		authHalfList = CollectionUtils.valueOfList(StringUtils.trimNull(cfg.get("auth.half")));
	}

	public BusinessResponse handler(BusinessRequest request) {
		// 如果是非认证服务->直接跳过
		String key = request.getKey();
		if (authIgnoreList.contains(key)) {
			return new BusinessResponse();
		}
		// 如果是半认证服务->尝试认证
		else if (authHalfList.contains(key)) {
			check(request);
			return new BusinessResponse();
		} else {
			BusinessResponse response = check(request);
			if (response.getCode() != BusinessConst.RES_CODE_SUCCESS) {
				return response;
			}
			return new BusinessResponse();
		}
	}

	@BusinessMethod
	public BusinessResponse check(BusinessRequest request) {
		BusinessResponse response = new BusinessResponse();
		String token = StringUtils.trimNull(request.getExtData(BusinessConst.EXT_TOKEN_ID));
		String key = PRE + token;
		String session = null;
		if (!StringUtils.isEmpty(token)) {
			session = RedisUtils.get(key);
		}
		if (StringUtils.isEmpty(session)) {
			response.setCode(BusinessConst.RES_CODE_ERROR_BUIS_AUTH);
			response.setMsg("权限认证失败");
		} else {
			RedisUtils.expire(key, sessionTimeout);
			Map<String, Object> data = FwUtils.getJsonService().toMap(session);
			request.getExtData().put(BusinessConst.EXT_USER_ID, data.get("id"));
			request.getExtData().put(BusinessConst.EXT_APP_CODE, data.get("appCode"));
			request.getExtData().put(BusinessConst.EXT_TENANT_CODE, data.get("tenantCode"));
			response.setData(data);
		}
		return response;
	}

}
